package de.uni_mannheim.informatik.ai.dame_ai.dame.application;

import java.util.Observable;
import java.util.Observer;
import java.util.Random;

import de.uni_mannheim.informatik.ai.dame_ai.dame.domain.Board;
import de.uni_mannheim.informatik.ai.dame_ai.dame.domain.GameLogic;
import de.uni_mannheim.informatik.ai.dame_ai.dame.domain.GameStatus;
import de.uni_mannheim.informatik.ai.dame_ai.dame.domain.Move;
import de.uni_mannheim.informatik.ai.dame_ai.dame.domain.Piece;
import de.uni_mannheim.informatik.ai.dame_ai.dame.domain.Player;




public class AIPlayer implements Runnable, Observer{
	//GameLogic gameLogic;
	Board currentBoard;
	Player currentPlayer;
	Player ownPlayer;
	Player opponent;
	DameFacade controller;
	private Thread aiThread = null; 
	private boolean makeMove;
	public AIPlayer(Player aiPlayer, Player opponent, DameFacade controller){
		this.ownPlayer = aiPlayer;
		this.opponent = opponent;
		this.controller = controller;
		makeMove =false;
		start();
	}
	
	synchronized public boolean isMakeMove() {
		return makeMove;
	}

	public void setMakeMove(boolean makeMove) {
		this.makeMove = makeMove;
	}

	@Override
	public void run() {
		while(!isStop()){
			System.out.println("Waiting");
			if(isTurn()){
				if(!isStop()){
					System.out.println("Calculating");
					Move moves = calculateNextMove();
					try {
						Thread.sleep(1000l);
					} catch (InterruptedException e) {
					}
					setTurn(false);
					
					if(!isStop())controller.makeMove(moves.getFromPos(), moves.getToPos());
				}
			}
		}
		
	}
	boolean isTurn = false;
	synchronized public void setTurn(boolean isTurn){
		this.isTurn = isTurn;
		if(isTurn)notifyAll();
	}
	synchronized public boolean isTurn(){
		if(isTurn){
			return true;
		} else {
			try {
				wait();
				
			} catch (InterruptedException e) {
			}
			return true;
		}
	}
	boolean stop = false;
	synchronized public void setStop(boolean stop){
		this.stop = stop;
		this.isTurn = false;
		if(stop)notifyAll();
	}
	synchronized public boolean isStop(){
		return stop;
	}
	synchronized public void start(){
		if ( aiThread == null ) { 
            aiThread = new Thread(this); 
            aiThread.start(); 
        } 

	}
	/**
	 * @param gameStatus This is the new gamestatus
	 * @param obj This is the obj which sent the event
	 */
	@Override
	synchronized public void update(Observable obj, Object gameStatus) {
		if(gameStatus instanceof GameStatus) {
			GameStatus temp = (GameStatus)gameStatus;
			currentPlayer = temp.getCurrentPlayer();
			System.out.println("New Current Player: "+currentPlayer);
			currentBoard = Board.copyBoard(temp.getBoard());
			if(currentPlayer.equals(ownPlayer)){
				if(temp.isGameOver()){
					setStop(true);
				} else {
					setTurn(true);
				}
			}
			
		}
		
	}
	/** 
	 * 
	 * @param pieces The current gamestatus
	 * @return All possible moves of the current player
	 */
	private Move[] getAllPossibleMoves(Piece[] pieces, Player player){
		Move[] moves = GameLogic.getAllPossibleMoves(pieces,player);
		Move[] jumpMoves = GameLogic.getAllPossibleJumpMoves(moves);
		if(jumpMoves.length>0) moves = jumpMoves;
		return moves;
	}
	Random random = new Random();
	private Move calculateNextMove(){
		Move[] moves = getAllPossibleMoves(currentBoard.getPiecesStatus(), currentPlayer);
		int nextMove = random.nextInt(moves.length);
		
		return moves[nextMove];
		
		
	}
}
